Skip to content

Conversation

peterfriese
Copy link
Contributor

@peterfriese peterfriese commented Sep 28, 2025

To better align the Firebase Auth SDK with modern Swift concurrency, this PR introduces AsyncStream-based APIs for observing authentication state and ID token changes.

Key Features & Benefits

  • Modern Concurrency: New authStateChanges and idTokenChanges properties on Auth return an AsyncStream<User?>, allowing developers to use for await loops to monitor authentication events, which is more idiomatic in modern Swift.
  • Improved Ergonomics: These new APIs provide a more intuitive and readable alternative to the traditional closure-based listeners (addStateDidChangeListener and addIDTokenDidChangeListener).
  • Resource Safety: The streams are designed to be safely cancelled, preventing potential resource leaks. This is validated by comprehensive unit tests.

Implementation Details

  • The new async properties are housed in a new FirebaseAuth/Sources/Auth+Async.swift file.
  • Unit tests have been added in FirebaseAuth/Tests/Unit/AuthAsyncTests.swift to cover sign-in, sign-out, token refresh, and stream cancellation scenarios.
  • The FirebaseAuth/CHANGELOG.md has been updated to reflect these new features.
  • The new APIs are documented with clear usage examples, following Apple's documentation best practices.

Example Usage

Monitoring Authentication State

func monitorAuthState() async {
  for await user in Auth.auth().authStateChanges {
    if let user = user {
      print("User signed in: \(user.uid)")
      // Update UI or perform actions for a signed-in user.
    } else {
      print("User signed out.")
      // Update UI or perform actions for a signed-out state.
    }
  }
}

Monitoring ID Token Changes

func monitorIDTokenState() async {
  for await user in Auth.auth().idTokenChanges {
    if let user = user {
      print("ID token changed for user: \(user.uid)")
      // The user's ID token has been refreshed.
      // You can get the new token by calling user.getIDToken()
      do {
        let token = try await user.getIDToken()
        print("New ID token: \(token)")
        // Send the new token to your backend server, etc.
      } catch {
        print("Error getting ID token: \(error)")
      }
    }
  }
}

This commit introduces an `AsyncStream`-based API for observing authentication state changes, aligning the Firebase Auth SDK with modern Swift concurrency patterns.

The new `authStateChanges` computed property on `Auth` returns an `AsyncStream<User?>` that emits the current user whenever the authentication state changes. This provides a more ergonomic alternative to the traditional closure-based `addStateDidChangeListener`.

Key changes include:
- The implementation of `authStateChanges` in a new `Auth+Async.swift` file.
-  Comprehensive unit tests in `AuthAsyncTests.swift` covering the stream's behavior for sign-in, sign-out, and cancellation scenarios to prevent resource leaks.
- An entry in the `FirebaseAuth/CHANGELOG.md` for the new feature.
- Detailed API documentation for `authStateChanges`, including a clear usage example, following Apple's documentation best practices.
@peterfriese peterfriese self-assigned this Sep 28, 2025
@peterfriese peterfriese linked an issue Sep 28, 2025 that may be closed by this pull request
This commit introduces an `AsyncStream`-based API for observing ID token changes, aligning the Firebase Auth SDK with modern Swift concurrency patterns.

The new `idTokenChanges` computed property on `Auth` returns an `AsyncStream<User?>` that emits the current user whenever the ID token changes. This provides a more ergonomic alternative to the traditional closure-based `addIDTokenDidChangeListener`.

Key changes include:
- The implementation of `idTokenChanges` in `Auth+Async.swift`.
- Comprehensive unit tests in `IdTokenChangesAsyncTests.swift` covering the stream's behavior.
- Renamed `AuthAsyncTests.swift` to `AuthStateChangesAsyncTests.swift` to better reflect its content.
@peterfriese peterfriese marked this pull request as ready for review September 30, 2025 09:06
@ncooke3
Copy link
Member

ncooke3 commented Oct 2, 2025

/gemini review

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces AsyncStream-based APIs for observing authentication state and ID token changes, which is a great step towards modernizing the Firebase Auth SDK for Swift concurrency. The implementation is clean, well-documented, and includes a good set of unit tests.

My review includes a few suggestions to enhance the new APIs and tests:

  • Broadening the API availability to support older OS versions where Swift concurrency is available.
  • Improving the robustness of the unit tests by replacing Task.sleep with expectations.
  • Refactoring duplicated setup code in the tests to improve maintainability.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Implement AsyncStream support for Firebase Auth
3 participants